/********************************************************************************
*                                                                               *
* kWookaApplicationConfigPanel.cpp -- Springboot Application's config           *
*                                                                               *
* Copyright (c) Fengren Technology(Guangzhou) Co.LTD. All rights reserved.      *
*                                                                               *
********************************************************************************/


#include "kWookaApplicationConfigPanel.hpp"

#include "kWooka_ids.h"
#include "kWookaApplicationViewPanel.hpp"
#include "kWookaProjectInfo.hpp"
#include <wx/zipstrm.h>
#include <wx/wfstream.h>
#include <wx/txtstrm.h>

BEGIN_EVENT_TABLE(kWookaApplicationConfigPanel, wxPanel)
    ////Manual Code Start
    ////Manual Code End
    //EVT_KEY_DOWN(kPosSimpleCheckoutPanel::OnKeyCharEvent)
    EVT_BUTTON(ID_WXBUTTON_ADD_RECORD, kWookaApplicationConfigPanel::OnAddRecord)
    EVT_BUTTON(ID_WXBUTTON_DELETE_RECORD, kWookaApplicationConfigPanel::OnDeleteRecord)
    EVT_BUTTON(ID_WXBUTTON_APPLY_RECORD, kWookaApplicationConfigPanel::OnApplyGrid)
    EVT_BUTTON(ID_WXBUTTON_BROWSE, kWookaApplicationConfigPanel::OnBrowse)
    EVT_SIZING(kWookaApplicationConfigPanel::OnResize)
END_EVENT_TABLE()



kWookaApplicationConfigPanel::kWookaApplicationConfigPanel(wxWindow *parent, wxWindowID id, const wxString& WXUNUSED(title), const wxPoint &position, const wxSize& size, long style)
: wxPanel(parent, id, position, size, style)
{
    CreateGUIControls();
}

kWookaApplicationConfigPanel::~kWookaApplicationConfigPanel()
{
    wxLogDebug(wxT("kWookaApplicationConfigPanel destroyed."));
}

void kWookaApplicationConfigPanel::CreateGUIControls()
{
    //Do not add custom code between
    //GUI Items Creation Start and GUI Items Creation End
    //wxDev-C++ designer will remove them.
    //Add the custom code before or after the blocks
    ////GUI Items Creation Start
    kSource = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxPoint(140, 8), wxSize(140, 24));
    kBtnBrowse = new wxButton(this, ID_WXBUTTON_BROWSE, _("Browse"), wxDefaultPosition, wxSize(100, 20), 0);
    wxStaticText* lblFatJar = new wxStaticText(this, wxID_STATIC, _("SpringBoot JAR"), wxDefaultPosition, wxSize(140, 24), 0);
    kSource->SetEditable(false);
    CreateSearchPanel();

    wxSize size = this->GetClientSize();
    
    WxGrid1 = new wxGrid(this, ID_WXGRID1, wxPoint(10, 370), wxSize(699, 160));
    WxGrid1->SetDefaultColSize(100);
    WxGrid1->SetDefaultRowSize(25);
    WxGrid1->SetRowLabelSize(50);
    WxGrid1->SetColLabelSize(25);
    WxGrid1->CreateGrid(0, 3, wxGrid::wxGridSelectRowsOrColumns);
    WxGrid1->SetColLabelValue(0, _("CONFIG KEY"));
    WxGrid1->SetColLabelValue(1, _("VALUE"));
    WxGrid1->SetColLabelValue(2, _("ENV VARIABLE"));
    WxGrid1->SetVirtualSize(0, 2000);
    
    
    
    WxGrid1->SetColSize(0, 450);
    WxGrid1->SetColSize(1, 450);
    WxGrid1->SetColSize(1, 120);
    WxGrid1->EnableEditing(true);
    
    //WxGrid1->SetColSize(9, 0);
    
    
    
    WxBtnDeleteRecord = new wxButton(this, ID_WXBUTTON_DELETE_RECORD, _("DELETE"), wxPoint(324, 472), wxSize(120, 33), 0, wxDefaultValidator, _T("WxButtonDELETERECORD"));
    WxBtnAddRecord = new wxButton(this, ID_WXBUTTON_ADD_RECORD, _("ADD"), wxPoint(324, 472), wxSize(120, 33), 0, wxDefaultValidator, _T("WxButtonADDRECORD"));
    WxBtnApplyRecord = new wxButton(this, ID_WXBUTTON_APPLY_RECORD, _("APPLY"), wxPoint(324, 472), wxSize(120, 33), 0, wxDefaultValidator, _T("WxButtonADDRECORD"));
    wxStaticText* lblConfigList = new wxStaticText(this, wxID_ANY, _("CONFIGURATIONS FOR STARTING THE APPLICATION"), wxPoint(20, 8), wxSize(240, 24));

    wxBoxSizer* itemBoxSizer1 = new wxBoxSizer(wxVERTICAL);
    wxBoxSizer* itemBoxSizer2 = new wxBoxSizer(wxVERTICAL);
    wxBoxSizer* itemBoxSizer3 = new wxBoxSizer(wxHORIZONTAL);
    wxBoxSizer* itemBoxSizer4 = new wxBoxSizer(wxHORIZONTAL);

    
    itemBoxSizer4->Add(lblFatJar, 0, wxEXPAND | wxALL, 5);
    itemBoxSizer4->Add(kSource, 1, wxEXPAND | wxALL, 5);
    itemBoxSizer4->Add(kBtnBrowse, 0, wxEXPAND | wxALL, 5);

    itemBoxSizer2->Add(lblConfigList, 0, wxEXPAND | wxALL, 5);
    itemBoxSizer2->Add(WxGrid1, 1, wxEXPAND | wxALL, 5);
    itemBoxSizer3->Add(WxBtnApplyRecord, 0, wxSTRETCH_NOT | wxLEFT, 12);
    itemBoxSizer3->Add(WxBtnAddRecord, 0, wxSTRETCH_NOT | wxLEFT, 12);
    itemBoxSizer3->Add(WxBtnDeleteRecord, 0, wxSTRETCH_NOT | wxLEFT, 12);
    itemBoxSizer2->Add(itemBoxSizer3, 0, wxALIGN_RIGHT | wxRIGHT, 0);

    itemBoxSizer1->Add(itemBoxSizer4, 0, wxEXPAND | wxALIGN_TOP | wxLEFT, 5);
    itemBoxSizer1->Add(m_JavaVMConfigPanel, 0, wxEXPAND | wxALL, 0);
    itemBoxSizer1->Add(itemBoxSizer2, 1, wxEXPAND | wxALL,  5);
    //itemBoxSizer1->Add(WxStaticBox2, 0, wxEXPAND | wxTOP,  5);
    
    this->SetSizerAndFit(itemBoxSizer1);
//    SetTitle(_("kpos"));
//    SetIcon(wxNullIcon);
    SetSize(8,8,1238,530);
    Center();

    ////GUI Items Creation End
}

/**
    Create the Search panel
    1. Status, 2. Order No, 3. Order Name, 4. Pay Time
 */
void kWookaApplicationConfigPanel::CreateSearchPanel() {
    m_JavaVMConfigPanel = new kWookaApplicationJavaVMPanel(this);
    //wxBoxSizer* boxSizer = new wxBoxSizer(wxVERTICAL);
    //boxSizer->Add(m_JavaVMConfigPanel, 0, wxEXPAND | wxALIGN_CENTER | wxALL, 5);
}

void kWookaApplicationConfigPanel::OnKeyCharEvent(wxKeyEvent& event){
    if (event.GetKeyCode() == WXK_RETURN){
    }
}


void kWookaApplicationConfigPanel::OnResize(wxSizeEvent& WXUNUSED(event)) {
    wxSize size = this->GetClientSize();
    WxGrid1->SetColSize(0, 30);
    WxGrid1->SetColSize(1, size.x / 3);
    WxGrid1->SetColSize(2, size.x / 3);
    WxGrid1->SetColSize(3, 150);
}

void kWookaApplicationConfigPanel::SetViewPanel(kWookaApplicationViewPanel* vp) {
    m_viewpanel = vp;
}

kWookaApplicationViewPanel* kWookaApplicationConfigPanel::GetViewPanel() {
    return m_viewpanel;
}

void kWookaApplicationConfigPanel::UpdateConfigItem(kWookaAppItemInfo* appitem) {
    m_appItem = appitem;
    if (m_appItem == NULL) {
        this->kSource->SetValue(wxT(""));
        this->m_JavaVMConfigPanel->UpdateJvmConfig(NULL);
    }
    else {
        this->kSource->SetValue(m_appItem->source);
        this->m_JavaVMConfigPanel->UpdateJvmConfig(&m_appItem->jvmConfig);
    }

    if (WxGrid1 != NULL) {
        if (WxGrid1->GetNumberRows() > 0) {
            WxGrid1->DeleteRows(0, WxGrid1->GetNumberRows());
        }
        if (m_appItem != NULL) {
            for (size_t t = 0; t < m_appItem->appConfigs.Count(); t++) {
                kWookaAppConfigItemInfo ci = m_appItem->appConfigs[t];
                WxGrid1->AppendRows();
                WxGrid1->SetCellValue(t, 0, ci.configKey);
                WxGrid1->SetCellValue(t, 1, ci.configValue);
                WxGrid1->SetCellValue(t, 2, wxT("env") == ci.configType ? wxT("1"): wxT(""));
                WxGrid1->SetCellEditor(t, 2, new wxGridCellBoolEditor());
                WxGrid1->SetCellRenderer(t, 2, new wxGridCellBoolRenderer());
            }
        }
    }
}

void kWookaApplicationConfigPanel::OnAddRecord(wxCommandEvent& WXUNUSED(event)) {
    if (WxGrid1 != NULL) {
        WxGrid1->AppendRows();
        WxGrid1->SetCellEditor(WxGrid1->GetNumberRows() - 1, 2, new wxGridCellBoolEditor());
        WxGrid1->SetCellRenderer(WxGrid1->GetNumberRows() - 1, 2,  new wxGridCellBoolRenderer());

    }
}

void kWookaApplicationConfigPanel::OnDeleteRecord(wxCommandEvent& WXUNUSED(event)) {
    if (WxGrid1 != NULL) {
        if (WxGrid1->GetGridCursorRow() >= 0) {
            WxGrid1->DeleteRows(WxGrid1->GetGridCursorRow());
        }
    }
}

void kWookaApplicationConfigPanel::OnApplyGrid(wxCommandEvent& WXUNUSED(event)) {
    
    if (WxGrid1 != NULL) {
        this->m_appItem->appConfigs.Clear();
        for (int i = 0; i < WxGrid1->GetNumberRows(); i++) {
            wxString key = WxGrid1->GetCellValue(i, 0);
            wxString value = WxGrid1->GetCellValue(i, 1);
            wxString env = WxGrid1->GetCellValue(i, 2);
            if (key.Length() > 0) {
                kWookaAppConfigItemInfo configItem;
                configItem.configKey = key;
                configItem.configValue = value;
                configItem.configType = env == wxT("1") ? wxT("env"): wxT("other");
                this->m_appItem->appConfigs.Insert(configItem, 0);
            }
        }
    }

}


void kWookaApplicationConfigPanel::OnBrowse(wxCommandEvent& WXUNUSED(event)) {
    if (m_appItem != NULL) {
        wxFileDialog fd(this, _("Open a SpringBoot application"), wxEmptyString, wxEmptyString, _("SpringBoot Fat JAR (*.jar)|*.jar|" "All files (*.*)|*.*"));
        wxString filenameWin("META-INF\\MANIFEST.MF");
        wxString filenameUnix("META-INF/MANIFEST.MF");
        kWookaAppItemInfo appitem;

        if (fd.ShowModal() == wxID_OK) {
            wxString fl = fd.GetPath();
            wxFileInputStream in(fl);
            wxZipInputStream zip(in);
            wxZipEntry* entry = zip.GetNextEntry();
            while (entry != NULL)
            {
                wxString name = entry->GetName();
                wxFileName fname(name);
                wxString FilePath = fname.GetPath();
                if (name == filenameWin || name == filenameUnix) {
                    // here to parse the file
                    wxTextInputStream txt(zip);
                    appitem.source = fl;
                    wxString line = txt.ReadLine();
                    while (line.IsNull() == false) {
                        wxString nextline = txt.ReadLine();
                        if (line.StartsWith("Implementation-Title:")) {
                            appitem.name = line.SubString(wxString("Implementation-Title:").Length(), line.Length()).Trim().Trim(false);
                            if (nextline.IsNull() == false && nextline.Find(wxString(":")) == -1) {
                                appitem.name += nextline.Trim().Trim(false);
                                nextline = txt.ReadLine();
                            }
                        }
                        else if (line.StartsWith("Implementation-Version:")) {
                            appitem.version = line.SubString(wxString("Implementation-Version:").Length(), line.Length()).Trim().Trim(false);
                            if (nextline.IsNull() == false && nextline.Find(wxString(":")) == -1) {
                                appitem.version += nextline.Trim().Trim(false);
                                nextline = txt.ReadLine();
                            }
                        }
                        else if (line.StartsWith("Implementation-Vendor-Id:")) {
                            appitem.groupId = line.SubString(wxString("Implementation-Vendor-Id:").Length(), line.Length()).Trim().Trim(false);
                            if (nextline.IsNull() == false && nextline.Find(wxString(":")) == -1) {
                                appitem.groupId += nextline.Trim().Trim(false);
                                nextline = txt.ReadLine();
                            }
                        }
                        else if (line.StartsWith("Start-Class:")) {
                            appitem.startClass = line.SubString(wxString("Start-Class:").Length(), line.Length()).Trim().Trim(false);
                            if (nextline.IsNull() == false && nextline.Find(wxString(":")) == -1) {
                                appitem.startClass += nextline.Trim().Trim(false);
                                nextline = txt.ReadLine();
                            }
                        }

                        line = nextline;
                    }
                    delete entry;
                    break;
                }

                //    Implementation - Title: chimes - ac - auth
                //    Implementation - Version : 1.2.0 - SNAPSHOT
                //    Built - By : mekot
                //    Implementation - Vendor - Id : com.kiloseed.chimes
                //    Start - Class : com.kiloseed.ac.auth.ChimesAcAuthApplication
                delete entry;
                entry = zip.GetNextEntry();
            }

            /// Here we will check the relative version to the current
            if (!appitem.name.IsEmpty() && !appitem.groupId.IsEmpty() && !appitem.startClass.IsEmpty()) {
                if (m_appItem->name == appitem.name && m_appItem->groupId == appitem.groupId) {
                    m_appItem->source = appitem.source;
                    if (!appitem.version.IsEmpty()) {
                        m_appItem->version = appitem.version;
                    }
                    if (!appitem.startClass.IsEmpty()) {
                        m_appItem->startClass = appitem.startClass;
                    }
                    kSource->SetValue(m_appItem->source);
                }
                else {
                    wxMessageBox(_("You choosed a difference springboot application. Please make sure and choose another one."));
                }
            } else {
                wxMessageBox(_("Please choose a valid springboot fat jar package."));
            }
        }
    }
}

